#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "util/rgbtobmp.h"

#define _DEBUG_ printf("-----------\n");

void pixel_rgb565_to_rgb24(const unsigned char *p16,unsigned char *p24) //将16bit的像素转化为24bit的像素
{
    unsigned char R,G,B;
    B=*(unsigned short*)p16 & 0x01F;
    G=(*(unsigned short*)p16 & 0x7E0) >> 5;
    R=(*(unsigned short*)p16 >> 11 ) & 0x1F;
    *(p24+0)=B << 2;
    *(p24+1)=G << 1;
    *(p24+2)=R << 2;
}

void image16_to_image24(const unsigned char *image16, unsigned char *image24, int biWidth, int biHeight)
{
    unsigned char *p16 = (unsigned char *)image16;
    unsigned char *p24 = image24;
    int i, j;
    for(i=0; i < biHeight; i++)
    {
        p16 =(unsigned char *)image16 + (biHeight - i - 1) * biWidth * 2;
        p24 =(unsigned char *)image24 + i * biWidth * 3;

        for(j=0; j<biWidth; j++, p16+=2, p24+=3)
        {
            pixel_rgb565_to_rgb24(p16, p24);
        }
    }
}

void save_rgb565_to_bmpfile(unsigned char *rgbdata, int width, int height, char *FileName)
{
    //BITMAPFILEHEADER bmp_fileheader;
    int IMAGESIZE16 = width * height * 2;
    int IMAGESIZE24 = (IMAGESIZE16 / 2) * 3;
    int widthAlignBytes = (((width * 24) + 31) & (~31)) / 8 ; //每行实际占用的大小（每行都被填充到一个4字节边界）
    int DIBSize = widthAlignBytes * height ;  //buffer的大小 （字节为单位）
    unsigned char bmp_fileheader[14];   //位图文件头
    //unsigned char imagedata16[IMAGESIZE16];
    unsigned char imagedata24[IMAGESIZE24];
    BITMAPINFOHEADER bmp_infoheader;    //位图信息头

    //位图文件头
    //因为字节对齐的问题，所以位图文件头用数组来定义
    *(WORD *)bmp_fileheader = 'B' | 'M' << 8; //bfType 文件标识'BM'
    *(DWORD *)(bmp_fileheader + 2) = 14 + 40 + DIBSize;     //bfSize 文件的大小
    *(DWORD *)(bmp_fileheader + 6) = 0; //bfReserved1 和 bfReserved2
    *(DWORD *)(bmp_fileheader + 10) = 54;   //bfOffBits 图象数据RGBA的起始地址的偏移值  为54

    //位图信息头
    bmp_infoheader.biSize = 40;
    bmp_infoheader.biWidth = width;                     //图像width
    bmp_infoheader.biHeight = height;                       //图像height
    bmp_infoheader.biPlanes = 1;
    bmp_infoheader.biBitCount = 24;                     //像素精度
    bmp_infoheader.biCompression = 0;
    bmp_infoheader.biSizeImage = DIBSize;               //图像大小
    bmp_infoheader.biXPelsPerMeter = 0;
    bmp_infoheader.biYPelsPerMeter = 0;
    bmp_infoheader.biClrUsed = 0;
    bmp_infoheader.biClrImportant = 0;

    printf("image16_to_image24 start width = %d, height = %d.\n", width, height);
    image16_to_image24((const unsigned char *)rgbdata, imagedata24, width, height);
    printf("image16_to_image24 end.\n");

    int k = 0;
    FILE *file = fopen(FileName, "wb");
    if(file != NULL)
    {
        fwrite(bmp_fileheader, 14, 1, file);
        fwrite(&bmp_infoheader, 40, 1, file);
        //按行写入
        if (widthAlignBytes == width * 3)
        {
            fwrite(imagedata24, IMAGESIZE24, 1, file);
        }
        else
        {
            // 每一行单独写入
            const static DWORD DWZERO = 0;
            for (k = 0; k < height; k++)
            {
                fwrite(imagedata24 + k * width * 3, 1, width * 3,file);
                fwrite(&DWZERO, 1, widthAlignBytes - width * 3, file);
            }
        }
        fclose(file);
    }
}

int save_rgb565_to_bmpmem(unsigned char *rgbdata, int width, int height, char *mem)
{
    //BITMAPFILEHEADER bmp_fileheader;
    int IMAGESIZE16 = width * height * 2;
    int IMAGESIZE24 = (IMAGESIZE16 / 2) * 3;
    unsigned char bmp_fileheader[14];   //位图文件头
    //unsigned char imagedata16[IMAGESIZE16];
    unsigned char imagedata24[IMAGESIZE24];
    BITMAPINFOHEADER bmp_infoheader;    //位图信息头

    //位图文件头
    //因为字节对齐的问题，所以位图文件头用数组来定义
    *(WORD *)bmp_fileheader = 'B' | 'M' << 8; //bfType 文件标识'BM'
    *(DWORD *)(bmp_fileheader + 2) = 14 + 40 + IMAGESIZE24;     //bfSize 文件的大小
    *(DWORD *)(bmp_fileheader + 6) = 0; //bfReserved1 和 bfReserved2
    *(DWORD *)(bmp_fileheader + 10) = 54;   //bfOffBits 图象数据RGBA的起始地址的偏移值  为54

    //位图信息头
    bmp_infoheader.biSize = 40;
    bmp_infoheader.biWidth = width;                     //图像width
    bmp_infoheader.biHeight = height;                       //图像height
    bmp_infoheader.biPlanes = 1;
    bmp_infoheader.biBitCount = 24;                     //像素精度
    bmp_infoheader.biCompression = 0;
    bmp_infoheader.biSizeImage = IMAGESIZE24;               //图像大小
    bmp_infoheader.biXPelsPerMeter = 0;
    bmp_infoheader.biYPelsPerMeter = 0;
    bmp_infoheader.biClrUsed = 0;
    bmp_infoheader.biClrImportant = 0;


    printf("image16_to_image24 start width = %d,height = %d.\n", width, height);
    image16_to_image24((const unsigned char *)rgbdata, imagedata24, width, height);
    printf("image16_to_image24 end.\n");
    memcpy(mem, bmp_fileheader, 14);
    memcpy(mem + 14, &bmp_infoheader, 40);
    memcpy(mem + 54, imagedata24, IMAGESIZE24);
    return IMAGESIZE24 + 54;
}
